package com.tvunetworks.center.device.controller;

import com.github.pagehelper.PageInfo;
import com.tvunetworks.center.common.constant.LocalConstant;
import com.tvunetworks.center.common.model.LoginUser;
import com.tvunetworks.center.common.model.ps.PSR;
import com.tvunetworks.center.common.model.ps.PST;
import com.tvunetworks.center.common.util.Result;
import com.tvunetworks.center.common.util.ResultUtil;
import com.tvunetworks.center.device.annotation.Logined;
import com.tvunetworks.center.device.model.MyDevice;
import com.tvunetworks.center.device.model.PtsPrs;
import com.tvunetworks.center.device.model.json.DeviceIpPort;
import com.tvunetworks.center.device.model.vo.NotConnectR;
import com.tvunetworks.center.device.service.*;
import com.tvunetworks.center.device.service.feign.UserFeignService;
import com.tvunetworks.center.device.service.impl.DevicePairService;
import com.tvunetworks.center.device.util.RedisUtil;
import com.tvunetworks.center.gs.model.Device;
import net.spy.memcached.MemcachedClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;

/**
 * @author lebronchen
 * @program: tvucc-aggregator
 * @description: DebugController
 * @create: 2020-03-12 10:40
 **/
@RestController
@RequestMapping("/debug")
public class DebugController {

    @Autowired
    private DeviceService deviceService;
    @Autowired
    private DeviceGeoService deviceGeoService;
    @Autowired
    @Qualifier("ccMemcacheClient")
    private MemcachedClient ccMemcacheClient;
    @Autowired
    @Qualifier("tpdsMemcacheClient")
    private MemcachedClient tpdsMemcacheClient;
    @Autowired
    @Qualifier("psMemcacheClient")
    private MemcachedClient psMemcacheClient;
    @Autowired
    private DevicePairService devicePairService;
    @Autowired
    private UserFeignService userFeignService;

    @Autowired
    private PidPortMappingService pidPortMappingService;
    @Autowired
    private TimeLockMsgService timeLockMsgService;
    @Autowired
    private RedisUtil redisUtil;
    @Resource(name = "redisTpdsTemplate")
    private RedisTemplate tpdsRedisTemplate;

    /**
     * 获取device的ip
     *
     * @param pids pids
     * @return list
     * @throws ExecutionException   编译异常
     * @throws InterruptedException 编译异常
     */
    @PostMapping("/getDeviceIpPort")
    public Result getDeviceIpPort(@RequestBody List<String> pids) throws ExecutionException, InterruptedException {
        List<DeviceIpPort> list = deviceService.getDeviceIpPort(pids);
        return ResultUtil.success(list);
    }

    /**
     * 获取和R配对的T
     *
     * @param rid rid
     * @return list
     */
    @GetMapping("/listRPairT")
    public Result listRPairT(@RequestParam String rid) {
        List<String> list = devicePairService.listRPairT(rid);
        return ResultUtil.success(list);
    }

    /**
     * 获取和T配对的R
     *
     * @param tid tid
     * @return list
     */
    @GetMapping("/listTPairR")
    public Result listTPairR(@RequestParam String tid) {
        List<String> list = devicePairService.listTPairR(tid);
        return ResultUtil.success(list);
    }

    /**
     * 获取Device状态
     *
     * @param peerId peerId
     * @return Result
     */
    @GetMapping("/getCurrentDevice")
    public Result getCurrentDevice(@RequestParam String peerId) {
        peerId = peerId.toLowerCase();
        Map<String, Object> map = new HashMap<>();
        Device device = deviceService.getCurrentDevice(peerId);
        map.put("memcache", device);
        MyDevice dbDevice = deviceService.getDBDevice(peerId);
        map.put("DB", dbDevice);
        if (device != null) {
            if (LocalConstant.DeviceType.R.equals(device.getType())) {
                PSR psr = PtsPrs.getPrs().get(peerId);
                map.put("peerService", psr);
            } else if (LocalConstant.DeviceType.T.equals(device.getType())) {
                PST pst = PtsPrs.getPts().get(peerId);
                map.put("peerService", pst);
            }
        }
        return ResultUtil.success(map);
    }

    /**
     * 获取device状态
     *
     * @param peerIds peerIds
     * @return Result
     */
    @GetMapping("/listCurrentDevice")
    public Result listCurrentDevice(@RequestParam String peerIds) {
        List<Device> devices = deviceService.listCurrentDevice(Arrays.asList(peerIds.split(",")));
        return ResultUtil.success(devices);
    }

    @Autowired
    private CustomizedShareService customizedShareService;

    /**
     * @param loginUser loginUser
     * @param peerId    peerId
     * @return success
     */
    @GetMapping("/createAutoShareAccount")
    public Result createAutoShareAccount(@Logined LoginUser loginUser, String peerId) {
        customizedShareService.createAutoShareAccount(loginUser.getId(), peerId);
        return ResultUtil.success();
    }

    /**
     * @param key  key
     * @param type type
     * @return success
     */
    @GetMapping("/memcache/get")
    public Result memcacheGet(@RequestParam String key, @RequestParam(required = false, defaultValue = "1") int type) {
        Object o;
        if (type == 1) {
            o = ccMemcacheClient.get(key);
        } else if (type == 2) {
            o = tpdsMemcacheClient.get(key);
        } else {
            o = psMemcacheClient.get(key);
        }
        return ResultUtil.success(o);
    }

    /**
     * 删除缓存中的数据
     *
     * @param key  key
     * @param type type
     * @return Result
     */
    @GetMapping("/memcache/delete")
    public Result memcacheDelete(@RequestParam String key, @RequestParam(required = false, defaultValue = "1") int type) {
        Object o;
        if (type == 1) {
            o = ccMemcacheClient.delete(key);
        } else if (type == 2) {
            o = tpdsMemcacheClient.delete(key);
        } else {
            o = psMemcacheClient.delete(key);
        }
        return ResultUtil.success(o);
    }

    /**
     * 查询没连接的R
     *
     * @param session  session
     * @param pageNum  pageNum
     * @param pageSize pageSize
     * @return list
     */
    @GetMapping("/listNotConnectR")
    public Result listNotConnectR(@RequestParam String session, @RequestParam(defaultValue = "1") int pageNum, @RequestParam(defaultValue = "50") int pageSize) {
        Result<LoginUser> checkSessionResult = userFeignService.getLoginUserWithNoCheck(session);
        if (!checkSessionResult.assertSuccess()) {
            return ResultUtil.noAuthority();
        }
        PageInfo<NotConnectR> list = deviceService.listNotConnectR(pageNum, pageSize);
        return ResultUtil.success(list);
    }

    /**
     * initDeviceGeoSchedule
     */
    @GetMapping("/initDeviceGeoSchedule")
    public void initDeviceGeoSchedule() {
        deviceGeoService.initDeviceGeo();
    }


    /**
     * 初始化tvu_device到t_pid_port_mapping，条件是type=R，且有IP
     *
     * @return success
     */
    @RequestMapping("initDeviceExistIpToPidPortMapping")
    public Result initDeviceExistIpToPidPortMapping() {
        pidPortMappingService.initDeviceExistIpToPidPortMapping();
        return ResultUtil.success();
    }

    /**
     * 初始化tvu_device到t_pid_port_mapping，条件是type=R，且有IP
     *
     * @return success
     */
    @RequestMapping("deletePidPortMapping")
    public Result deletePidPortMapping() {
        return ResultUtil.success(pidPortMappingService.deletePidPortMapping());
    }

    /**
     * 将t_pid_port_mapping表中的在线或live且domain为空的设备获取对应的domain并更新对应的domain
     *
     * @return map，key为SUCCESS，对应的value为成功的个数，key为FAILED，对应的value为失败个数，key为FailedPeerId，对应的value为失败的pid集合
     */
    @RequestMapping("initOnlineOrLiveReceiverDomainToPidPortMapping")
    public Result initOnlineOrLiveReceiverDomainToPidPortMapping() {
        return ResultUtil.success(pidPortMappingService.initOnlineOrLiveReceiverDomainToPidPortMapping());
    }

    /**
     * 将CC已停止但Receiver未停止timeLock时，需要向receiver服务重新下发timeLock的stop命令
     * @param eventId 已停止的eventId
     * @param rid 已停止的rid
     * @return 返回发送给receiver的消息
     */
    @RequestMapping("stopTimeLockMessageSendToReceiver")
    public Result stopTimeLockMessageSendToReceiver(@RequestParam("eventId") String eventId, @RequestParam("rid") String rid) {
        return ResultUtil.success(timeLockMsgService.stopTimeLockMessageSendToReceiver(eventId, rid));
    }

    /**
     * 查询redis中的指定key对应的值
     * @param key redis的key
     * @param type 0表示tpds的redis，1表示cc的redis
     * @return 返回redis中对应的值
     */
    @RequestMapping("/redis/get")
    public Result redisGet(@RequestParam String key, @RequestParam(required = false, defaultValue = "1") int type) {
        Object o;
        if (type == 1) {
            o = redisUtil.get(key);
        }else {
            o = tpdsRedisTemplate.opsForValue().get(key);
        }
        return ResultUtil.success(o);
    }

    /**
     * 获取redis中所有的rid集合
     * @return 返回所有的rId
     */
    @RequestMapping("getAllRIDByRedis")
    public Result getAllRIDByRedis() {
        return ResultUtil.success(deviceGeoService.getAllRIDByRedis());
    }

    /**
     * 获取redis中所有的tid集合
     * @return 返回所有的tId
     */
    @RequestMapping("getAllTIDByRedis")
    public Result getAllTIDByRedis() {
        return ResultUtil.success(deviceGeoService.getAllTIDByRedis());
    }
}
